import _ from 'lodash';Utility functions used elsewhere in the codebase. Most JavaScript files on the site use some functions defined in this file.
import _ from 'lodash';Generate an Event object for triggering a custom event.
function customEvent(name, detail) {
var evt = document.createEvent('Event');
evt.initEvent(name, true, true);
evt.detail = detail;
return evt;
}Add extra fields to a bounding box returned by getBBox. Specifically adds
details about the box’s axis points (used when positioning elements for
display).
ax, ax2, and ay
will be added if they are not already defined.function normalizeBBox(box) {
return _.defaults(box, {
ax: box.x,
ax2: box.x2,
ay: box.cy
});
}Positions a collection of items with their axis points aligned along a horizontal line. This leads to the items being spaced horizontally and effectively centered vertically.
function spaceHorizontally(items, options) {
var verticalCenter,
values;
options = _.defaults(options || {}, {
padding: 0
});
values = _.map(items, item => ({
box: normalizeBBox(item.getBBox()),
item
}));Calculate where the axis points should be positioned vertically.
verticalCenter = _.reduce(values,
(center, { box }) => Math.max(center, box.ay),
0);Position items with padding between them and aligned their axis points.
_.reduce(values, (offset, { item, box }) => {
item.transform(Snap.matrix()
.translate(offset, verticalCenter - box.ay));
return offset + options.padding + box.width;
}, 0);
}Positions a collection of items centered horizontally in a vertical stack.
function spaceVertically(items, options) {
var horizontalCenter,
values;
options = _.defaults(options || {}, {
padding: 0
});
values = _.map(items, item => ({
box: item.getBBox(),
item
}));Calculate where the center of each item should be positioned horizontally.
horizontalCenter = _.reduce(values,
(center, { box }) => Math.max(center, box.cx),
0);Position items with padding between them and align their centers.
_.reduce(values, (offset, { item, box }) => {
item.transform(Snap.matrix()
.translate(horizontalCenter - box.cx, offset));
return offset + options.padding + box.height;
}, 0);
}Creates a Promise that will be resolved after a specified delay.
function wait(delay) {
return new Promise((resolve, reject) => {
setTimeout(resolve, delay);
});
}Creates a Promise that will be resolved after 0 milliseconds. This is used to create a short delay that allows the browser to address any pending tasks while the JavaScript VM is not active.
function tick() {
return wait(0);
}Re-throws an exception asynchronously. This is used to expose an exception that was created during a Promise operation to be handled by global error handlers (and to be displayed in the browser’s debug console).
function exposeError(error) {
setTimeout(() => {
throw error;
}, 0);
}function icon(selector) {
return `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 8 8"><use xlink:href="${selector}" /></svg>`;
}Send tracking data.
function track() {
if (window.ga) {
ga.apply(ga, arguments);
} else {
console.debug.apply(console, arguments);
}
}
export default {
customEvent,
normalizeBBox,
spaceHorizontally,
spaceVertically,
wait,
tick,
exposeError,
icon,
track
};